#include "./simple_req.h"
#include "../driver/cmd_uart.h"
#include "../task/handler_task.h"
#include "./ota.h"
#include "../driver/ctrl.h"
#include "../task/water_heat_task.h"
#include "../task/steam_heat_task.h"
#include "../task/draw_task.h"
#include "../cfg/app_info.h"

namespace service::simple_req {

using namespace conn;
using namespace driver;
using namespace utils;
using namespace task;
using namespace cfg;

static void on_get_task_info(const Message &msg) {
    const task::TaskInfo& task_info = handlerTask.task_info();
    cmdUart.simple_res(msg, ec::OK, task_info.seq, task_info.cmd);
}

static void on_parts_ctrl(const Message &msg) {
    uint8_t id, val;
    Error err = msg.parse_req(id, val);
    if (err) {
        goto finish;
    }
    if (id >= parts::END) {
        err = ec::INVALID;
        goto finish;
    }
    switch (val) {
        case 0: ctrl.open(id); break;
        case 1: ctrl.close(id); break;
        default: err = ec::INVALID; break;
    }
finish:
    cmdUart.simple_res(msg, err);
}

static void on_get_param(const Message &msg) {
    uint8_t key;
    uint16_t v;
    Error err = msg.parse_req(key);
    if (err) {
        goto finish;
    }
    switch (key) {
        case 0: v = appInfo->flow_count_1000L; break;
        case 1: v = appInfo->steam_heat_temp;  break;
        case 2: v = appInfo->steam_heat_kpa; break;
        case 3: v = appInfo->steam_heat_timeout / 60 / 1000; break;
        case 4: v = appInfo->water_heat_temp; break;
        case 5: v = appInfo->water_heat_timeout / 60 / 1000; break;
        case 6: v = appInfo->draw_timeout / 60 / 1000; break;
        default: err = ec::INVALID; break; 
    }
finish:
    cmdUart.simple_res(msg, err, v);
}

static void on_draw_heat_ctrl(const Message &msg) {
    uint8_t c;
    Error err = msg.parse_req(c);
    if (err) {
        goto finish;
    }
    switch (c) {
        case 0: drawTask.idle(); break;
        case 1: drawTask.stop(); break;
        case 2: waterHeatTask.idle(); break;
        case 3: waterHeatTask.stop(); break;
        case 4: steamHeatTask.idle(); break;
        case 5: steamHeatTask.stop(); break;
        default: err = ec::INVALID; break;
    }
finish: 
    cmdUart.simple_res(msg, err);
}

void dispatch(const Message& msg) {

    switch (msg.cmd()) {
        case proto::CMD_OTA_START: ota::on_start(msg); break;
        case proto::CMD_OTA_TRANSLATE: ota::on_translate(msg); break;
        case proto::CMD_OTA_COMPLETE: ota::on_complete(msg); break;
        case proto::CMD_GET_TASK_INFO: on_get_task_info(msg); break;
        case proto::CMD_PARTS_CTRL: on_parts_ctrl(msg); break;
        case proto::CMD_PARAM: on_get_param(msg); break;
        case proto::CMD_DRAW_HEAT_CTRL: on_draw_heat_ctrl(msg); break;
    }
}

}

